package com.andatsoft.laisim.activity;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.StateListDrawable;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.MediaStore;
import android.text.TextUtils.TruncateAt;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewManager;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.ViewSwitcher.ViewFactory;

import com.andatsoft.laisim.R;
import com.andatsoft.laisim.adapter.LibraryAllSongsAdapter;
import com.andatsoft.laisim.adapter.LibraryGridAdapter;
import com.andatsoft.laisim.adapter.LibraryGridAlbumAdapter;
import com.andatsoft.laisim.adapter.LibraryTwoLineListAdapter;
import com.andatsoft.laisim.db.DataBaseAccess;
import com.andatsoft.laisim.dialog.CreatePlaylistDialog;
import com.andatsoft.laisim.dialog.CreatePlaylistFromToolBoxDialog;
import com.andatsoft.laisim.dialog.MessageBox;
import com.andatsoft.laisim.entity.AlbumItem;
import com.andatsoft.laisim.entity.Song;
import com.andatsoft.laisim.entity.TwoLineItem;
import com.andatsoft.laisim.service.PlayerService;
import com.andatsoft.laisim.theme.ThemeManager;
import com.andatsoft.laisim.utils.Common;
import com.andatsoft.laisim.utils.ToastMessage;
import com.andatsoft.laisim.utils.Utils;
import com.andatsoft.laisim.view.MyViewFlipper;
import com.andatsoft.laisim.view.MyViewFlipper.IFlipperIndexChanged;
import com.andatsoft.laisim.view.SlimProgressBar;
import com.andatsoft.laisim.view.SlimProgressBar.SlimProgressClicked;
import com.andatsoft.laisim.view.Toolbox;

public class LibraryActivity extends BaseActivity implements
		IFlipperIndexChanged {
	public static final int TYPE_SONG = 0;
	public static final int TYPE_ALBUM = 1;
	public static final int TYPE_ARTIST = 2;
	public static final int TYPE_GENRE = 3;
	public static final int TYPE_FOLDER = 4;

	private GridView mGridViewLibrary;
	private GridView mGridViewAlbums;
	private MyViewFlipper mViewFlipper;
	private ListView mListView;
	private GridView mTwoLineListView;
	private TextView mBtnBack;
	private TextView mBtnAlbumBack;
	private TextView mBtnTwoLineBack;
	private TextView mBtnCreatePlaylist;
	private TextSwitcher mTsNumberRecored;
	private SlimProgressBar mProgressTransparent;
	private LinearLayout mLayoutBgTransparent;
	private Toolbox mToolbox;

	private LibraryGridAdapter mGridLibAdapter;
	private LibraryGridAlbumAdapter mGridAlbumAdapter;
	private LibraryTwoLineListAdapter mTwoLineListAdapter;
	private LibraryAllSongsAdapter mListAllSongAdapter;

	private List<AlbumItem> mListAlbum;
	private List<Song> mListSong;
	private List<TwoLineItem> mListTwoLineItem;

	// Index
	private int mGridViewIndex = 2;// default is all song
	private int mTwoLineListViewIndex = -1;
	private int mGridViewAlbumIndex = -1;
	private int mListViewSongIndex = -1;
	private int mGridViewIndexSaved = -1;
	private int mTwoLineListViewIndexSaved = -1;
	private int mGridViewAlbumIndexSaved = -1;
	private int mListViewSongIndexSaved = -1;
	private int mPlaySource = -1; // 0: 2 line, 1: Album, 2: songs
	private int mListMode = 0;// 0: artist, 1: genre, 2: folder, 3: playlist
	private int mNextDisplayedChild;
	private int mViewPaddingTop = 0;
	private int mTypeList = -1; // 0: Song, 1: Album, 2: artist, 3:genre,
								// 4:folder

	// because when update new playlist, the index show the wrong value,
	// we need to update this index when a new playlist added.
	private String mNameOfSelectedPlaylist;
	private int mCurrentPlaylistId;
	private String mArtistSelected = "";
	private boolean mIsDirectToAlbum;

	private DataBaseAccess mDataBase;

	// Player service
	private PlayerService mPlayerService;
	private boolean mIsBoundService;

	private ServiceConnection mPlayerServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mPlayerService = null;
			Log.d("SerConnect", "Disconnect");
		}

		// called when bind service called.
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mPlayerService = ((PlayerService.LocalBinder) service).getService();
			Log.d("SerConnect", "Connected");
			mListViewSongIndexSaved = mPlayerService.getCurrentSongIndex();

		}
	};

	public void doBindService() {
		bindService(new Intent(LibraryActivity.this, PlayerService.class),
				mPlayerServiceConnection, Context.BIND_AUTO_CREATE);
		// Log.d("Bind", "bind" + bo);
		mIsBoundService = true;
	}

	public void doUnBindService() {
		unbindService(mPlayerServiceConnection);
		mIsBoundService = false;
	}

	private BroadcastReceiver mBroadcastUpdateSongInfo = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			if (mPlayerService == null)
				return;
			mListViewSongIndexSaved = mPlayerService.getCurrentSongIndex();
			mListViewSongIndex = mListViewSongIndexSaved;
			mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
			mListAllSongAdapter.notifyDataSetChanged();
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_library);
		ThemeManager.loadSkin(getApplicationContext(),
				ThemeManager.LIBRARY_ACTIVYTY);
		initVars();
		new InitTask().execute(2);
		initViews();
		setupListeners();

	}

	private void initVars() {
		mListAlbum = new ArrayList<AlbumItem>();
		mListSong = new ArrayList<Song>();
		mListTwoLineItem = new ArrayList<TwoLineItem>();

		mGridAlbumAdapter = new LibraryGridAlbumAdapter(
				getApplicationContext(), mListAlbum);
		mGridLibAdapter = new LibraryGridAdapter(getApplicationContext());
		mListAllSongAdapter = new LibraryAllSongsAdapter(
				getApplicationContext(), mListSong, getLayoutInflater());
		mTwoLineListAdapter = new LibraryTwoLineListAdapter(
				getApplicationContext(), mListTwoLineItem);

	}

	private void initViews() {
		mProgressTransparent = (SlimProgressBar) findViewById(R.id.progress_lib_transparent_background);
		mProgressTransparent.setMax(100);
		mProgressTransparent.setProgress(90);
		mLayoutBgTransparent = (LinearLayout) findViewById(R.id.layout_lib_background);
		setAlpha(mLayoutBgTransparent, 0.9f);
		mToolbox = (Toolbox) findViewById(R.id.layout_tool_box_library);
		mGridViewLibrary = (GridView) findViewById(R.id.grid_view_library);
		mGridViewAlbums = (GridView) findViewById(R.id.grid_view_library_albums);
		mGridViewAlbums.setAdapter(mGridAlbumAdapter);

		mBtnBack = (TextView) findViewById(R.id.tv_library_back);
		if (mBtnBack != null) {
			if (getSelectedTheme() != null)
				mBtnBack.setTextColor(getSelectedTheme().getNormalTextColor());
			setBackgroundColorForView(mBtnBack);
		}
		mBtnAlbumBack = (TextView) findViewById(R.id.tv_library_album_back);
		if (mBtnAlbumBack != null) {
			if (getSelectedTheme() != null)
				mBtnAlbumBack.setTextColor(getSelectedTheme()
						.getNormalTextColor());
			setBackgroundColorForView(mBtnAlbumBack);
		}
		mBtnTwoLineBack = (TextView) findViewById(R.id.tv_library_two_line_back);
		if (mBtnTwoLineBack != null) {
			if (getSelectedTheme() != null)
				mBtnTwoLineBack.setTextColor(getSelectedTheme()
						.getNormalTextColor());
			setBackgroundColorForView(mBtnTwoLineBack);
		}
		mBtnCreatePlaylist = (TextView) findViewById(R.id.tv_library_create_playlist);
		if (mBtnCreatePlaylist != null) {
			if (getSelectedTheme() != null)
				mBtnCreatePlaylist.setTextColor(getSelectedTheme()
						.getNormalTextColor());
			setBackgroundColorForView(mBtnCreatePlaylist);
		}

		mListView = (ListView) findViewById(R.id.list_view_library);
		mListView.setAdapter(mListAllSongAdapter);
		mTwoLineListView = (GridView) findViewById(R.id.gridview_library_two_line_item);
		mTwoLineListView.setAdapter(mTwoLineListAdapter);

		mViewFlipper = (MyViewFlipper) findViewById(R.id.view_slipper_library);
		mTsNumberRecored = (TextSwitcher) findViewById(R.id.tv_library_number_of_record);
		if (mTsNumberRecored != null) {
			mTsNumberRecored.setFactory(new ViewFactory() {

				@Override
				public View makeView() {
					TextView tv = new TextView(getApplicationContext());
					if (getSelectedTheme() != null)
						tv.setTextColor(getSelectedTheme().getNormalTextColor());
					tv.setTextSize(15f);
					tv.setSingleLine(true);
					tv.setEllipsize(TruncateAt.MARQUEE);
					FrameLayout.LayoutParams pa = new FrameLayout.LayoutParams(
							FrameLayout.LayoutParams.MATCH_PARENT, 50,
							Gravity.BOTTOM);
					tv.setLayoutParams(pa);
					return tv;
				}
			});
			mTsNumberRecored.setInAnimation(AnimationUtils.loadAnimation(
					getApplicationContext(), R.anim.fade_in_fast));
			mTsNumberRecored.setOutAnimation(AnimationUtils.loadAnimation(
					getApplicationContext(), R.anim.fade_out_fast));
		}
	}

	private void fillData() {
		if (mGridViewLibrary == null)
			return;
		mGridViewLibrary.setAdapter(mGridLibAdapter);
	}

	private Animation mInAnimationLeftRight;
	private Animation mInAnimationRightLeft;

	private void setupAnimation() {
		mInAnimationLeftRight = AnimationUtils.loadAnimation(
				getApplicationContext(),
				R.anim.slide_left_to_right_fade_in_fast);
		mInAnimationLeftRight.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {
				mBtnAlbumBack.setEnabled(true);
				mBtnBack.setEnabled(true);
				mBtnTwoLineBack.setEnabled(true);
			}
		});
		mInAnimationRightLeft = AnimationUtils.loadAnimation(
				getApplicationContext(),
				R.anim.slide_right_to_left_fade_in_fast);
		mInAnimationRightLeft.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {
				mBtnAlbumBack.setEnabled(true);
				mBtnBack.setEnabled(true);
				mBtnTwoLineBack.setEnabled(true);
			}
		});
	}

	private void setupListeners() {
		mProgressTransparent.setOnSlimClicked(new SlimProgressClicked() {

			@Override
			public void onClick(int newProgress) {
				setAlpha(mLayoutBgTransparent, newProgress / 100.0f);
			}
		});
		setupAnimation();
		mViewFlipper.setOnFlipperIndexChanged(this);

		mBtnBack.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					Log.i("Btn ", "Btn up");
					mBtnAlbumBack.setEnabled(false);
					mBtnBack.setEnabled(false);
					mBtnTwoLineBack.setEnabled(false);
					// Setup animation
					mViewFlipper.setInAnimation(mInAnimationLeftRight);
					mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(
							getApplicationContext(),
							R.anim.slide_left_to_right_fade_out_fast));
					if (mNextDisplayedChild < 0)
						mNextDisplayedChild = 0;
					mViewFlipper.setDisplayedChild(mNextDisplayedChild);
					mNextDisplayedChild--;
					return true;
				}

				return false;
			}
		});

		mBtnAlbumBack.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					mBtnAlbumBack.setEnabled(false);
					mBtnBack.setEnabled(false);
					mBtnTwoLineBack.setEnabled(false);
					// Setup animation
					mViewFlipper.setInAnimation(mInAnimationLeftRight);
					mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(
							getApplicationContext(),
							R.anim.slide_left_to_right_fade_out_fast));
					if (mIsDirectToAlbum) {
						mViewFlipper.setDisplayedChild(0);
					} else {
						mViewFlipper.setDisplayedChild(mNextDisplayedChild);
					}
					return true;
				}

				return false;
			}
		});

		mBtnTwoLineBack.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					mBtnAlbumBack.setEnabled(false);
					mBtnBack.setEnabled(false);
					mBtnTwoLineBack.setEnabled(false);
					// Setup animation
					mViewFlipper.setInAnimation(mInAnimationLeftRight);
					mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(
							getApplicationContext(),
							R.anim.slide_left_to_right_fade_out_fast));
					mViewFlipper.setDisplayedChild(0);
					mBtnCreatePlaylist.setVisibility(View.GONE);
					return true;
				}

				return false;
			}
		});

		mBtnCreatePlaylist.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					Intent i = new Intent(LibraryActivity.this,
							CreatePlaylistDialog.class);
					startActivityForResult(i,
							Common.REQUEST_CODE_FOR_CREATE_PLAYLIST);
					return true;
				}

				return false;
			}
		});

		if (mGridViewLibrary == null)
			return;
		mGridViewLibrary.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
					long arg3) {
				// Setup animation
				mViewFlipper.setInAnimation(mInAnimationRightLeft);
				mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_right_to_left_fade_out_fast));
				mIsDirectToAlbum = false;
				mGridViewIndex = pos;
				switch (pos) {
				case 0:// Most played
					mListSong.clear();
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListSong.addAll(mDataBase.getMostPlayedSongs());
					if (pos != mGridViewIndexSaved) {
						mListViewSongIndex = -1;
						mListAllSongAdapter.setSelectedItem(-1);
					} else {
						if (mPlayerService != null) {
							mListViewSongIndex = getCurrentSongIndexById(mListSong);
						} else {
							mListViewSongIndex = mListViewSongIndexSaved;
						}
						mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
						mListView.setSelection(mListViewSongIndex);
					}
					mListAllSongAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(3);
					mNextDisplayedChild = 0;
					mTypeList = TYPE_SONG;
					break;
				case 1: // favorite
					mListSong.clear();
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListSong.addAll(mDataBase.getFavoriteSongs());

					if (pos != mGridViewIndexSaved) {
						mListViewSongIndex = -1;
						mListAllSongAdapter.setSelectedItem(-1);
					} else {
						if (mPlayerService != null) {
							mListViewSongIndex = mPlayerService
									.getCurrentSongIndex();
						} else {
							mListViewSongIndex = mListViewSongIndexSaved;
						}
						mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
						mListView.setSelection(mListViewSongIndex);
					}
					mListAllSongAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(3);
					mNextDisplayedChild = 0;
					mTypeList = TYPE_SONG;
					break;
				case 2:// all songs
					mListSong.clear();
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListSong.addAll(mDataBase.getAllSong());

					if (pos != mGridViewIndexSaved) {
						mListViewSongIndex = -1;
						mListAllSongAdapter.setSelectedItem(-1);
					} else {
						if (mPlayerService != null) {
							mListViewSongIndex = mPlayerService
									.getCurrentSongIndex();
						} else {
							mListViewSongIndex = mListViewSongIndexSaved;
						}
						mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
						mListView.setSelection(mListViewSongIndex);
					}
					mListAllSongAdapter.notifyDataSetChanged();
					// mListView.setAdapter(new LibraryAllSongsAdapter(
					// getApplicationContext(), mListSong,
					// getLayoutInflater()));
					mViewFlipper.setDisplayedChild(3);
					mNextDisplayedChild = 0;
					mTypeList = TYPE_SONG;
					break;
				case 3:// albums
					mAlbumLengthLoaded = false;
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListAlbum.clear();
					mListAlbum.addAll(mDataBase.getAllAlbum());

					if (pos != mGridViewIndexSaved) {
						mGridViewAlbumIndex = -1;
						mGridAlbumAdapter.setSelectedItem(-1);
					} else {
						mGridAlbumAdapter
								.setSelectedItem(mGridViewAlbumIndexSaved);
					}
					mGridAlbumAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(2);
					mNextDisplayedChild = 0;
					mListMode = 0;
					mIsDirectToAlbum = true;
					mTypeList = TYPE_ALBUM;
					break;
				case 4:// artist
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListTwoLineItem.clear();
					mListTwoLineItem.addAll(mDataBase.getAllArtist());

					if (pos != mGridViewIndexSaved) {
						mTwoLineListViewIndex = -1;
						mTwoLineListAdapter.setSelectedItem(-1);
					} else {
						mTwoLineListAdapter
								.setSelectedItem(mTwoLineListViewIndexSaved);
						mTwoLineListView
								.setSelection(mTwoLineListViewIndexSaved);
					}

					mTwoLineListAdapter.notifyDataSetChanged();
					mListMode = 0;
					mViewFlipper.setDisplayedChild(1);
					mTypeList = TYPE_ARTIST;
					break;
				case 5:// genre
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListTwoLineItem.clear();
					mListTwoLineItem.addAll(mDataBase.getAllGenre());

					if (pos != mGridViewIndexSaved) {
						mTwoLineListViewIndex = -1;
						mTwoLineListAdapter.setSelectedItem(-1);
					} else {
						mTwoLineListAdapter
								.setSelectedItem(mTwoLineListViewIndexSaved);
						mTwoLineListView
								.setSelection(mTwoLineListViewIndexSaved);
					}

					mTwoLineListAdapter.notifyDataSetChanged();
					mListMode = 1;
					mViewFlipper.setDisplayedChild(1);
					mTypeList = TYPE_GENRE;
					break;
				case 6:// playlist
					mBtnCreatePlaylist.setVisibility(View.VISIBLE);
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListTwoLineItem.clear();
					mListTwoLineItem.addAll(mDataBase.getAllPlayList());

					if (pos != mGridViewIndexSaved) {
						mTwoLineListViewIndex = -1;
						mTwoLineListAdapter.setSelectedItem(-1);
					} else {
						updatePlaylistIndexById();
						mTwoLineListAdapter
								.setSelectedItem(mTwoLineListViewIndexSaved);
						mTwoLineListView
								.setSelection(mTwoLineListViewIndexSaved);
						if (mListTwoLineItem.size() > 0)
							mNameOfSelectedPlaylist = mListTwoLineItem
									.get(mTwoLineListViewIndexSaved).name;
					}

					mTwoLineListAdapter.notifyDataSetChanged();
					mListMode = 3;
					mViewFlipper.setDisplayedChild(1);
					break;
				case 7:// folder
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListTwoLineItem.clear();
					mListTwoLineItem.addAll(mDataBase.getAllSongFolder());

					if (pos != mGridViewIndexSaved) {
						mTwoLineListViewIndex = -1;
						mTwoLineListAdapter.setSelectedItem(-1);
					} else {
						mTwoLineListAdapter
								.setSelectedItem(mTwoLineListViewIndexSaved);
						mTwoLineListView
								.setSelection(mTwoLineListViewIndexSaved);
					}
					mTwoLineListAdapter.notifyDataSetChanged();
					mListMode = 2;
					mViewFlipper.setDisplayedChild(1);
					mTypeList = TYPE_FOLDER;
					break;
				case 8:// has lyrics
					mListSong.clear();
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListSong.addAll(mDataBase.getSongsHasLyrics());

					if (pos != mGridViewIndexSaved) {
						mListViewSongIndex = -1;
						mListAllSongAdapter.setSelectedItem(-1);
					} else {
						if (mPlayerService != null) {
							mListViewSongIndex = mPlayerService
									.getCurrentSongIndex();
						} else {
							mListViewSongIndex = mListViewSongIndexSaved;
						}
						mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
						mListView.setSelection(mListViewSongIndex);
					}
					mListAllSongAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(3);
					mNextDisplayedChild = 0;
					mTypeList = TYPE_SONG;
					break;
				default:// error
					break;
				}
			}
		});

		mTwoLineListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
					long arg3) {
				// Setup animation
				mViewFlipper.setInAnimation(mInAnimationRightLeft);
				mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_right_to_left_fade_out_fast));
				mIsDirectToAlbum = false;
				TwoLineItem ti = mListTwoLineItem.get(pos);
				mTwoLineListViewIndex = pos;
				mDataBase = DataBaseAccess.getInstance(getApplicationContext());
				if (mListMode == 0)// artist
				{
					mAlbumLengthLoaded = false;
					mListAlbum.clear();
					mListAlbum.addAll(mDataBase.getAlbumByArtist(ti.name));

					if (pos != mTwoLineListViewIndexSaved) {
						mGridAlbumAdapter.setSelectedItem(-1);
					} else {
						mGridAlbumAdapter
								.setSelectedItem(mGridViewAlbumIndexSaved);
						mGridViewAlbums.setSelection(mGridViewAlbumIndexSaved);
					}
					mGridAlbumAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(2);
					mNextDisplayedChild = 1;
					mListMode = 0;
				} else if (mListMode == 1)// genre
				{
					mAlbumLengthLoaded = false;
					mListAlbum.clear();
					mListAlbum.addAll(mDataBase.getAlbumByGenre(ti.name));

					if (pos != mTwoLineListViewIndexSaved) {
						mGridAlbumAdapter.setSelectedItem(-1);
					} else {
						mGridAlbumAdapter
								.setSelectedItem(mGridViewAlbumIndexSaved);
						mGridViewAlbums.setSelection(mGridViewAlbumIndexSaved);
					}
					mGridAlbumAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(2);
					mNextDisplayedChild = 1;
				} else if (mListMode == 2)// folder
				{
					mListSong.clear();
					mListSong.addAll(mDataBase
							.getSongsByFolder(mListTwoLineItem.get(pos).name));

					if (pos != mTwoLineListViewIndexSaved) {
						mListAllSongAdapter.setSelectedItem(-1);
					} else {
						if (mPlayerService != null) {
							mListViewSongIndex = mPlayerService
									.getCurrentSongIndex();
						} else {
							mListViewSongIndex = mListViewSongIndexSaved;
						}
						mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
						mListView.setSelection(mListViewSongIndex);
					}
					mListAllSongAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(3);
					mNextDisplayedChild = 1;
				} else if (mListMode == 3)// playlist
				{
					int playlistId = mListTwoLineItem.get(pos).id;
					mCurrentPlaylistId = playlistId;
					mListSong.clear();
					mListSong.addAll(mDataBase.getSongByPlaylist(playlistId));

					if (pos != mTwoLineListViewIndexSaved) {
						mListAllSongAdapter.setSelectedItem(-1);
					} else {
						if (mPlayerService != null) {
							mListViewSongIndex = mPlayerService
									.getCurrentSongIndex();
							updateSongIndexById();
						} else {
							mListViewSongIndex = mListViewSongIndexSaved;
							updateSongIndexById();
						}
						mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
						mListView.setSelection(mListViewSongIndex);
					}
					mListAllSongAdapter.notifyDataSetChanged();
					mViewFlipper.setDisplayedChild(3);
					mNextDisplayedChild = 1;
				}

			}
		});

		mGridViewAlbums.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
					long arg3) {
				// Setup animation
				mViewFlipper.setInAnimation(mInAnimationRightLeft);
				mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_right_to_left_fade_out_fast));

				AlbumItem ai = mListAlbum.get(pos);
				mGridViewAlbumIndex = pos;
				mDataBase = DataBaseAccess.getInstance(getApplicationContext());
				mListSong.clear();
				if (mListMode == 0) // artist
				{
					mListSong.addAll(mDataBase.getSongsFromAlbum(ai.name,
							ai.artist));
				} else if (mListMode == 1)// genre
				{
					mListSong.addAll(mDataBase.getSongsFromAlbumAndGenre(
							ai.name, ai.artist, ai.genre));
				}

				if (pos != mGridViewAlbumIndexSaved) {
					mListAllSongAdapter.setSelectedItem(-1);
				} else {
					if (mPlayerService != null) {
						mListViewSongIndex = mPlayerService
								.getCurrentSongIndex();
					} else {
						mListViewSongIndex = mListViewSongIndexSaved;
					}
					mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
					mListView.setSelection(mListViewSongIndex);
				}
				mListAllSongAdapter.notifyDataSetChanged();
				mViewFlipper.setDisplayedChild(3);
				mNextDisplayedChild = 2;
			}
		});

		mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
					long arg3) {
				mListViewSongIndex = pos;
				mPlaySource = 2;
				mTypeList = TYPE_SONG;

				if (mListMode == 3) {
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mDataBase.setPlayingPlaylist(mCurrentPlaylistId, 1);
				} else {
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mDataBase.resetPlayingPlaylist();
				}

				// Save data.
				new InitTask().execute(1);

				// Finish
				mPlayerService.setPlaylist(mListSong);
				mPlayerService.resetAndPlay(mListViewSongIndex);

				mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
				mListViewSongIndexSaved = mListViewSongIndex;
				mListAllSongAdapter.notifyDataSetChanged();

				mGridViewIndexSaved = mGridViewIndex;
				mGridLibAdapter.setSelectedItem(mGridViewIndex);
				mGridLibAdapter.notifyDataSetChanged();

				// LibraryActivity.this.setResult(Common.RESULT_CODE_LIBRARY_MAIN);
				// LibraryActivity.this.finish();
			}
		});

		mTwoLineListView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View arg0, MotionEvent e) {
				mViewPaddingTop = (int) e.getY();
				return false;
			}
		});
		mTwoLineListView
				.setOnItemLongClickListener(new OnItemLongClickListener() {

					@Override
					public boolean onItemLongClick(AdapterView<?> adapterView,
							View view, int pos, long arg3) {
						showToolBox(mTwoLineListView);
						mArtistSelected = mListTwoLineItem.get(pos).name;
						// Get songs
						mDataBase = DataBaseAccess
								.getInstance(getApplicationContext());
						mPlaySource = 0;
						mTwoLineListViewIndex = pos;
						mListSong.clear();
						// Init data
						if (mListMode == 0)// artist
						{
							mListSong.addAll(mDataBase
									.getSongByArtist(mArtistSelected));
							mTypeList = TYPE_ARTIST;

						} else if (mListMode == 1)// genre
						{
							mListSong.addAll(mDataBase
									.getSongByGenre(mArtistSelected));
							mTypeList = TYPE_GENRE;

						} else if (mListMode == 2)// folder
						{
							mListSong.addAll(mDataBase
									.getSongsByFolder(mArtistSelected));
							mTypeList = TYPE_FOLDER;
						} else if (mListMode == 3)// playlist
						{
							int playlistId = mListTwoLineItem.get(pos).id;
							mListSong.addAll(mDataBase
									.getSongByPlaylist(playlistId));
							mTypeList = -1;
						}

						return true;
					}
				});

		mGridViewAlbums.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				mViewPaddingTop = (int) event.getY();
				return false;
			}
		});

		mGridViewAlbums
				.setOnItemLongClickListener(new OnItemLongClickListener() {

					@Override
					public boolean onItemLongClick(AdapterView<?> arg0,
							View arg1, int pos, long arg3) {
						showToolBox(mGridViewAlbums);
						String alName = mListAlbum.get(pos).name;
						String alArtist = mListAlbum.get(pos).artist;
						// Get songs
						mDataBase = DataBaseAccess
								.getInstance(getApplicationContext());
						mPlaySource = 1;// Album
						mGridViewAlbumIndex = pos;
						mTwoLineListViewIndex = -1;
						mTypeList = TYPE_ALBUM;
						mListSong.clear();
						mListSong.addAll(mDataBase.getSongsFromAlbum(alName,
								alArtist));

						return true;
					}
				});

		mListView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				mViewPaddingTop = (int) event.getY();
				return false;
			}
		});

		mListView.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int pos, long arg3) {
				showToolBox(mListView);
				mListViewSongIndex = pos;
				mPlaySource = 2;
				mTypeList = TYPE_SONG;
				return true;
			}
		});

	}

	private int getCurrentSongIndexById(List<Song> src) {
		if (mPlayerService == null)
			return -1;
		if (mPlayerService.getCurrentSong() == null)
			return -1;

		int id = mPlayerService.getCurrentSong().getId();
		for (int i = 0; i < src.size(); i++) {
			if (id == src.get(i).getId())
				return i;
		}
		return -1;

	}

	private void updatePlaylistIndexById() {
		mDataBase = DataBaseAccess.getInstance(getApplicationContext());
		int pId = mDataBase.getPlayingPlaylistId();
		for (int i = 0; i < mListTwoLineItem.size(); i++) {
			if (pId == mListTwoLineItem.get(i).id) {
				mTwoLineListViewIndex = i;
				mTwoLineListViewIndexSaved = i;
				break;
			}

		}
	}

	private void updateSongIndexById() {
		mDataBase = DataBaseAccess.getInstance(getApplicationContext());
		int pId = mDataBase.getPlayingPlaylistId();
		int sId = mDataBase.getPlayingSongIdInPlaylist(pId);
		for (int i = 0; i < mListSong.size(); i++) {
			if (sId == mListSong.get(i).getId()) {
				mListViewSongIndex = i;
				mListViewSongIndexSaved = i;
				break;
			}

		}
	}

	private void closeToolbox() {
		mToolbox.close(mAnimatorEventEx);
	}

	private boolean mFinishWhenCloseToolbox = false;

	private com.nineoldandroids.animation.Animator.AnimatorListener mAnimatorEventEx = new com.nineoldandroids.animation.Animator.AnimatorListener() {

		@Override
		public void onAnimationStart(com.nineoldandroids.animation.Animator arg0) {

		}

		@Override
		public void onAnimationRepeat(
				com.nineoldandroids.animation.Animator arg0) {

		}

		@Override
		public void onAnimationEnd(com.nineoldandroids.animation.Animator arg0) {
			unbindDrawables(mToolbox.getContent());
			mToolbox.setVisibility(View.GONE);
			if (mFinishWhenCloseToolbox)
				LibraryActivity.this.finish();
		}

		@Override
		public void onAnimationCancel(
				com.nineoldandroids.animation.Animator arg0) {

		}
	};

	private MessageBox mMessageBox;
	private boolean mIsMessageBoxShowing;

	private void showToolBox(AdapterView<?> adapterView) {
		if (mToolbox.isShowing())
			return;
		mToolbox.setContentLayout(R.layout.tool_box_library);
		mToolbox.show();
		if (adapterView.equals(mListView)) {
			mToolbox.findViewById(R.id.layout_library_extra).setVisibility(
					View.VISIBLE);
			createExtrasToolbox();
		}
		final TextView btnPlay = (TextView) mToolbox
				.findViewById(R.id.tv_library_play);
		if (getSelectedTheme() != null)
			btnPlay.setTextColor(getSelectedTheme().getNormalTextColor());
		setBackgroundColorForView(btnPlay);
		btnPlay.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					btnPlay.setEnabled(false);
					if (mListMode == 3) {
						mDataBase = DataBaseAccess
								.getInstance(getApplicationContext());
						int pId = mListTwoLineItem.get(mTwoLineListViewIndex).id;
						mDataBase.setPlayingPlaylist(pId, 1);
					} else {
						mDataBase = DataBaseAccess
								.getInstance(getApplicationContext());
						mDataBase.resetPlayingPlaylist();
					}

					// Save data.
					new InitTask().execute(1);

					// Finish
					mPlayerService.setPlaylist(mListSong);
					if (mPlaySource == 2) {
						mPlayerService.resetAndPlay(mListViewSongIndex);
					} else {
						mPlayerService.resetAndPlay(0);
					}
					mPlayerService.notifySkinReleased(false);
					LibraryActivity.this
							.setResult(Common.RESULT_CODE_LIBRARY_MAIN);
					// unbindDrawables(mToolBox);
					// mToolBox.setVisibility(View.GONE);
					mFinishWhenCloseToolbox = true;
					closeToolbox();
					// LibraryActivity.this.finish();
					return true;
				}
				return false;
			}
		});

		final TextView btnAddToPlaylist = (TextView) mToolbox
				.findViewById(R.id.tv_library_add_to_playlist);
		if (getSelectedTheme() != null)
			btnAddToPlaylist.setTextColor(getSelectedTheme()
					.getNormalTextColor());
		setBackgroundColorForView(btnAddToPlaylist);
		btnAddToPlaylist.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					btnAddToPlaylist.setEnabled(false);
					Intent i = new Intent(LibraryActivity.this,
							CreatePlaylistFromToolBoxDialog.class);
					i.putExtra(
							Common.INTENT_DATA_CREATE_PLAYLIST_FROM_TOOLBOX_CMD,
							mTypeList);
					switch (mTypeList) {
					case TYPE_SONG:
						// song
						i.putExtra(
								Common.INTENT_DATA_CREATE_PLAYLIST_FROM_TOOLBOX_SONGID,
								mListSong.get(mListViewSongIndex).getId());
						break;
					case TYPE_ALBUM:
						// album
						i.putExtra(
								Common.INTENT_DATA_CREATE_PLAYLIST_FROM_TOOLBOX_ALBUM,
								mListAlbum.get(mGridViewAlbumIndex).name
										+ "6_99_6"
										+ mListAlbum.get(mGridViewAlbumIndex).artist);
						break;
					case TYPE_ARTIST:
						// artist
						i.putExtra(
								Common.INTENT_DATA_CREATE_PLAYLIST_FROM_TOOLBOX_ARTIST,
								mListTwoLineItem.get(mTwoLineListViewIndex).name);
						break;
					case TYPE_GENRE:
						// genre
						i.putExtra(
								Common.INTENT_DATA_CREATE_PLAYLIST_FROM_TOOLBOX_GENRE,
								mListTwoLineItem.get(mTwoLineListViewIndex).name);
						break;
					case TYPE_FOLDER:
						// folder
						i.putExtra(
								Common.INTENT_DATA_CREATE_PLAYLIST_FROM_TOOLBOX_FOLDER,
								mListTwoLineItem.get(mTwoLineListViewIndex).name);
						break;

					default:
						break;
					}
					startActivityForResult(i,
							Common.REQUEST_CODE_FOR_CREATE_PLAYLIST);
					// unbindDrawables(mToolBox);
					// mToolBox.setVisibility(View.GONE);
					closeToolbox();
					return true;
				}
				return false;
			}
		});

		final TextView btnDel = (TextView) mToolbox
				.findViewById(R.id.tv_library_remove);
		if (getSelectedTheme() != null)
			btnDel.setTextColor(getSelectedTheme().getNormalTextColor());
		setBackgroundColorForView(btnDel);

		btnDel.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					btnDel.setEnabled(false);
					closeToolbox();
					mMessageBox = new MessageBox(getApplicationContext(), true);
					String content = "";
					if (mListSong.size() > 1) {
						content = mListSong.size()
								+ " "
								+ getString(R.string.message_box_delete_group_of_songs_plural);
					} else {
						content = mListSong.size()
								+ " "
								+ getString(R.string.message_box_delete_group_of_songs);
					}

					mMessageBox.setMessageContent(content);
					mMessageBox
							.setOkButtonOnTouchListener(new OnTouchListener() {

								@Override
								public boolean onTouch(View v, MotionEvent event) {
									if (!mIsMessageBoxReady)
										return true;
									switch (event.getAction()) {
									case MotionEvent.ACTION_DOWN:
										setAlpha(v, 0.5f);
										return true;

									case MotionEvent.ACTION_UP:
										setAlpha(v, 1.0f);
										mIsMessageBoxReady = false;
										if (mListMode == 3)// playlist
										{
											doDeletePlaylist(mListTwoLineItem
													.get(mTwoLineListViewIndex).id);
										} else {
											try {
												doDeleteLib();
											} catch (NullPointerException ne) {

											}
										}
										dismissMessageBox();
										break;
									}
									return false;
								}
							});
					mMessageBox
							.setCancelButtonOnTouchListener(new OnTouchListener() {

								@Override
								public boolean onTouch(View v, MotionEvent event) {
									if (!mIsMessageBoxReady)
										return true;
									switch (event.getAction()) {
									case MotionEvent.ACTION_DOWN:
										setAlpha(v, 0.5f);
										return true;

									case MotionEvent.ACTION_UP:
										setAlpha(v, 1.0f);
										mIsMessageBoxReady = false;
										dismissMessageBox();
										break;
									}
									return false;
								}
							});

					LinearLayout.LayoutParams pr = new LinearLayout.LayoutParams(
							LinearLayout.LayoutParams.MATCH_PARENT,
							LinearLayout.LayoutParams.MATCH_PARENT);
					addContentView(mMessageBox, pr);
					Animation animation = AnimationUtils.loadAnimation(
							getBaseContext(),
							R.anim.message_box_slide_top_to_bottom_fade_in);
					animation.setStartOffset(0);
					mMessageBox.getContent().startAnimation(animation);
					animation = AnimationUtils.loadAnimation(getBaseContext(),
							R.anim.message_box_bg_fade_in_fast);
					animation.setStartOffset(0);
					animation.setFillAfter(true);
					mMessageBox.getBackgroundLayout().startAnimation(animation);
					mIsMessageBoxShowing = true;

					return true;

				default:
					break;
				}
				return false;
			}

		});
		if (!adapterView.equals(mGridViewAlbums)) {
			if (mViewPaddingTop > mToolbox.getHeight() / 2)// below
			{
				mViewPaddingTop -= adapterView.getChildAt(0).getHeight();
			} else {
				mViewPaddingTop += adapterView.getChildAt(0).getHeight();
			}
		}
		mToolbox.getContent().setPadding(0, mViewPaddingTop, 0, 0);
	}

	private void createExtrasToolbox() {
		final TextView btnRingtone = (TextView) mToolbox
				.findViewById(R.id.tv_library_ringtone);
		if (getSelectedTheme() != null)
			btnRingtone.setTextColor(getSelectedTheme().getNormalTextColor());
		setBackgroundColorForView(btnRingtone);
		btnRingtone.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					btnRingtone.setEnabled(false);
					setAsRingtone(mListViewSongIndex);
					mToolbox.close();
					break;
				}
				return true;
			}
		});
		final TextView btnSend = (TextView) mToolbox
				.findViewById(R.id.tv_library_send);
		if (getSelectedTheme() != null)
			btnSend.setTextColor(getSelectedTheme().getNormalTextColor());
		setBackgroundColorForView(btnSend);
		btnSend.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					btnSend.setEnabled(false);
					sendFile(mListViewSongIndex);
					mToolbox.close();
					break;
				}
				return true;
			}
		});
		final TextView btnDetail = (TextView) mToolbox
				.findViewById(R.id.tv_library_detail);
		if (getSelectedTheme() != null)
			btnDetail.setTextColor(getSelectedTheme().getNormalTextColor());
		setBackgroundColorForView(btnDetail);
		btnDetail.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					btnDetail.setEnabled(false);
					goToDetail(mListViewSongIndex);
					mToolbox.close();
					break;
				}
				return true;
			}
		});
	}

	// ////////////////////////////////////////////////////////////////
	private void sendFile(int index) {
		if (mPlayerService != null) {
			Song s = mListSong.get(index);
			if (s == null)
				return;
			String path = s.getAddress();

			File file = new File(path);

			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_SEND);
			intent.setType("text/plain");
			intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
			startActivity(intent);
		}
	}

	private void goToDetail(int index) {
		if (mPlayerService != null) {
			Song s = mListSong.get(index);
			if (s == null)
				return;
			Intent i = new Intent(LibraryActivity.this,
					SongDetailsActivity.class);

			i.putExtra(MainActivity.INTENT_DATA_MAIN_VIEW_DETAILS_SONG_ID,
					s.getId());
			startActivity(i);
		}
	}

	private void applyRingtone(int index) {
		Song song = mListSong.get(index);
		if (song == null)
			return;
		// delete before add new ringtone
		Uri uriDel = MediaStore.Audio.Media.getContentUriForPath(mPlayerService
				.getCurrentSong().getAddress());
		getContentResolver()
				.delete(uriDel,
						MediaStore.MediaColumns.DATA + "=\""
								+ song.getAddress() + "\"", null);

		ContentValues values = new ContentValues();
		values.put(MediaStore.MediaColumns.DATA, song.getAddress());
		values.put(MediaStore.MediaColumns.TITLE, song.getTitle());
		values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg"); // assuming
																		// //
																		// course
		values.put(MediaStore.Audio.Media.ARTIST, song.getArtist());
		// values.put(MediaStore.Audio.Media.DURATION,
		// duration); //
		// doesn't appear to be necessary if you don't know
		values.put(MediaStore.Audio.Media.IS_RINGTONE, true);

		Uri uri = MediaStore.Audio.Media
				.getContentUriForPath(song.getAddress());
		Uri newUri = getContentResolver().insert(uri, values);

		RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(),
				RingtoneManager.TYPE_RINGTONE, newUri);
	}

	private void setAsRingtone(final int index) {
		if (mPlayerService != null) {
			OnTouchListener okEvent = new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {
					if (!mIsMessageBoxReady)
						return true;
					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						setAlpha(v, 0.5f);
						return true;
					case MotionEvent.ACTION_UP:
						setAlpha(v, 1.0f);
						mIsMessageBoxReady = false;
						dismissMessageBox();
						applyRingtone(index);
						new ToastMessage(getApplicationContext())
								.showLongMessage(getString(R.string.main_ringtone_toast_changed_ok));
						return true;
					default:
						break;
					}
					return false;
				}
			};

			OnTouchListener cancelEvent = new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {
					if (!mIsMessageBoxReady)
						return true;
					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						setAlpha(v, 0.5f);
						return true;
					case MotionEvent.ACTION_UP:
						setAlpha(v, 1.0f);
						mIsMessageBoxReady = false;
						dismissMessageBox();
						return true;

					default:
						break;
					}
					return false;
				}
			};
			if (!mIsMessageBoxReady)
				return;
			showMessageBox(getString(R.string.message_box_apply_ringtone)
					+ "\n\n" + mListSong.get(index).getTitle(), okEvent,
					cancelEvent);
		} else {
			new ToastMessage(getApplicationContext())
					.showLongMessage(getString(R.string.main_ringtone_toast_changed_not_ok));
		}
	}

	// ////////////////////////////////////////////////////////////////

	private void doDeletePlaylist(int id) {
		mDataBase = DataBaseAccess.getInstance(getApplicationContext());
		// check if the current playlist deleted
		boolean isNeedToChanged = false;
		if (id == mDataBase.getPlayingPlaylistId()) {
			isNeedToChanged = true;
			// update playing list to all song
			mDataBase.savePlayingSong(mDataBase.getAllSong());
			// save data
			SharedPreferences sP = getSharedPreferences(Common.SP_LIBRARY_NAME,
					Context.MODE_PRIVATE);
			SharedPreferences.Editor ed = sP.edit();
			ed.putInt(Common.SP_LIBRARY_PLAYING_SONG_INDEX, 0);
			ed.putInt(Common.SP_LIBRARY_PLAYING_LIB_INDEX, 2);
			ed.commit();
			mGridViewIndex = 2;
			mListViewSongIndex = 0;
			mListViewSongIndexSaved = mListViewSongIndex;
			mGridLibAdapter.setSelectedItem(mGridViewIndex);
			mGridLibAdapter.notifyDataSetChanged();
			mListAllSongAdapter.setSelectedItem(mListViewSongIndex);
			mListAllSongAdapter.notifyDataSetChanged();
		}
		mDataBase.deletePlaylist(id);

		mListTwoLineItem.remove(mTwoLineListViewIndex);
		mTwoLineListAdapter.notifyDataSetChanged();
		mTsNumberRecored.setText(getString(R.string.lib_text_total_found) + " "
				+ mListTwoLineItem.size());
		Intent i = new Intent(PlayerService.INTENT_PLAYLIST_CHANGED);

		if (isNeedToChanged) {
			i.putExtra(Common.INTENT_DATA_SONG_PLAYING_CHANGED, true);
			sendBroadcast(i);
		}

	}

	private void doDeleteLib() throws NullPointerException {
		// check if the playing song is deleted
		int songId = mPlayerService.getCurrentSong().getId();
		mDataBase = DataBaseAccess.getInstance(getApplicationContext());
		switch (mPlaySource) {
		case 0: // 2 line
			mListTwoLineItem.remove(mTwoLineListViewIndex);
			mTwoLineListAdapter.notifyDataSetChanged();
			mTsNumberRecored.setText(getString(R.string.lib_text_total_found)
					+ " " + mListTwoLineItem.size());
			mDataBase.deleteLibSongs(mListSong);
			break;
		case 1: // album
			mListAlbum.remove(mGridViewAlbumIndex);
			mGridAlbumAdapter.notifyDataSetChanged();
			mTsNumberRecored.setText(getString(R.string.lib_text_total_found)
					+ " " + mListAlbum.size());
			mDataBase.deleteLibSongs(mListSong);
			break;
		case 2: // songs
			List<Song> del = new ArrayList<Song>();
			del.add(mListSong.get(mListViewSongIndex));
			mDataBase.deleteLibSongs(del);
			mListSong.remove(mListViewSongIndex);
			mListAllSongAdapter.notifyDataSetChanged();
			mTsNumberRecored.setText(getString(R.string.lib_text_total_found)
					+ " " + mListSong.size());
			// mDataBase.deleteLibSongs(mListSong);
			mListAllSongAdapter.setSelectedItem(-1);
			break;
		}

		Intent i = new Intent(PlayerService.INTENT_PLAYLIST_CHANGED);
		if (mPlaySource == 2) {
			if (!isPlayingSongDeleted(mListSong, songId)) {
				i.putExtra(Common.INTENT_DATA_SONG_PLAYING_CHANGED, true);
			}
		} else {
			if (isPlayingSongDeleted(mListSong, songId)) {
				i.putExtra(Common.INTENT_DATA_SONG_PLAYING_CHANGED, true);
			}
		}
		sendBroadcast(i);
	}

	private boolean isPlayingSongDeleted(List<Song> src, int curId) {
		for (Song s : src) {
			if (curId == s.getId())
				return true;
		}
		return false;
	}

	private boolean mIsMessageBoxReady = true;

	private void dismissMessageBox() {
		Animation animation = AnimationUtils.loadAnimation(getBaseContext(),
				R.anim.message_box_slide_bottom_to_top_fade_out);
		animation.setStartOffset(0);
		animation.setFillAfter(true);
		mMessageBox.getContent().startAnimation(animation);
		mMessageBox.getContent().setVisibility(View.GONE);
		animation = AnimationUtils.loadAnimation(getBaseContext(),
				R.anim.message_box_bg_fade_out_fast);
		animation.setStartOffset(0);
		animation.setFillAfter(true);
		mMessageBox.getBackgroundLayout().startAnimation(animation);
		// mMessageBox.getBackgroundLayout().setClickable(false);

		animation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {

			}

			@Override
			public void onAnimationRepeat(Animation animation) {

			}

			@Override
			public void onAnimationEnd(Animation animation) {
				((ViewManager) mMessageBox.getParent()).removeView(mMessageBox);
				mMessageBox = null;
				mIsMessageBoxShowing = false;
				mIsMessageBoxReady = true;
			}
		});

	}

	private void showMessageBox(String content, OnTouchListener eventOk,
			OnTouchListener eventCancel) {
		mMessageBox = new MessageBox(getApplicationContext(), true);

		mMessageBox.setMessageContent(content);
		mMessageBox.setOkButtonOnTouchListener(eventOk);
		mMessageBox.setCancelButtonOnTouchListener(eventCancel);

		LinearLayout.LayoutParams pr = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.MATCH_PARENT,
				LinearLayout.LayoutParams.MATCH_PARENT);
		addContentView(mMessageBox, pr);
		Animation animation = AnimationUtils.loadAnimation(getBaseContext(),
				R.anim.message_box_slide_top_to_bottom_fade_in);
		animation.setStartOffset(0);
		mMessageBox.getContent().startAnimation(animation);
		animation = AnimationUtils.loadAnimation(getBaseContext(),
				R.anim.fade_in_fast);
		animation.setStartOffset(0);
		mMessageBox.getBackgroundLayout().startAnimation(animation);
		mIsMessageBoxShowing = true;
	}

	@Override
	public void onBackPressed() {
		if (mIsMessageBoxShowing) {
			dismissMessageBox();
		} else if (mToolbox.isShowing()) {
			closeToolbox();
		} else {
			LibraryActivity.this.setResult(Common.RESULT_CODE_LIBRARY_MAIN);
			this.finish();
			overridePendingTransition(R.anim.fade_in_fast, R.anim.fade_out_fast);
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		unbindDrawables(findViewById(R.id.root_view_library_activity));
		ThemeManager.getSelectedSkin().release(ThemeManager.LIBRARY_ACTIVYTY);
		System.gc();
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mIsBoundService)
			doUnBindService();
		unregisterReceiver(mBroadcastUpdateSongInfo);
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (!mIsBoundService)
			doBindService();
		registerReceiver(mBroadcastUpdateSongInfo, new IntentFilter(
				Common.INTENT_UPDATE_SONG_INFO));
		if (Utils.androidOs > Common.ANDROID_OS_GINGERBREAD) {
			StateListDrawable listSelector = createListSelector();
			mGridViewLibrary.setSelector(listSelector);
			mListView.setSelector(listSelector);
			mGridViewAlbums.setSelector(listSelector);
			mTwoLineListView.setSelector(listSelector);
		}
	}

	@SuppressLint("NewApi")
	private StateListDrawable createListSelector() {
		ColorDrawable clrPress = new ColorDrawable();
		clrPress.setColor(getSelectedTheme().getMPLSelectedTitleColor());

		StateListDrawable states = new StateListDrawable();
		states.addState(new int[] { android.R.attr.state_selected }, null);
		states.addState(new int[] { android.R.attr.state_pressed }, clrPress);

		return states;
	}

	public void savePlayingSongData() {
		SharedPreferences sP = getSharedPreferences(Common.SP_LIBRARY_NAME,
				Context.MODE_PRIVATE);
		SharedPreferences.Editor ed = sP.edit();
		ed.putInt(Common.SP_LIBRARY_PLAYING_LIB_INDEX, mGridViewIndex);
		ed.putInt(Common.SP_LIBRARY_PLAYING_TWO_LINE_INDEX,
				mTwoLineListViewIndex);
		ed.putInt(Common.SP_LIBRARY_PLAYING_ALBUM_INDEX, mGridViewAlbumIndex);
		ed.putInt(Common.SP_LIBRARY_PLAYING_SONG_INDEX, mListViewSongIndex);
		ed.putInt(Common.SP_LIBRARY_TWO_LINE_TYPE, mListMode);
		ed.putInt(Common.SP_LIBRARY_PLAY_SOURCE, mPlaySource);
		ed.commit();

		// Save list of songs
		mDataBase = DataBaseAccess.getInstance(getApplicationContext());
		mDataBase.savePlayingSong(mListSong);

	}

	public void applyPlayingData() {
		SharedPreferences sP = getSharedPreferences(Common.SP_LIBRARY_NAME,
				Context.MODE_PRIVATE);
		mGridViewIndexSaved = sP.getInt(Common.SP_LIBRARY_PLAYING_LIB_INDEX, 2);
		mTwoLineListViewIndexSaved = sP.getInt(
				Common.SP_LIBRARY_PLAYING_TWO_LINE_INDEX, -1);
		mGridViewAlbumIndexSaved = sP.getInt(
				Common.SP_LIBRARY_PLAYING_ALBUM_INDEX, -1);
		mListViewSongIndexSaved = sP.getInt(
				Common.SP_LIBRARY_PLAYING_SONG_INDEX, -1);
		mListMode = sP.getInt(Common.SP_LIBRARY_TWO_LINE_TYPE, 0);
		mPlaySource = sP.getInt(Common.SP_LIBRARY_PLAY_SOURCE, -1);

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == Common.REQUEST_CODE_FOR_CREATE_PLAYLIST) {
			if (resultCode == Common.RESULT_CODE_CREATE_PLAYLIST) {
				if (mListMode == 3) {
					// only update when displaying view is playlist
					mDataBase = DataBaseAccess
							.getInstance(getApplicationContext());
					mListTwoLineItem.clear();
					mListTwoLineItem.addAll(mDataBase.getAllPlayList());
					updatePlaylistIndex();
					mTwoLineListAdapter.setSelectedItem(mTwoLineListViewIndex);

					mTwoLineListAdapter.notifyDataSetChanged();
					mTsNumberRecored
							.setText(getString(R.string.lib_text_total_found)
									+ " " + mListTwoLineItem.size());
				}
				// if (data != null) {
				// int selectedId = data.getIntExtra(
				// Common.RESULT_DATA_CREATE_PLAYLIST_ID, -1);
				// mDataBase =
				// DataBaseAccess.getInstance(getApplicationContext());
				// int pId = mDataBase.getPlayingPlaylistId();
				// if (pId == selectedId) {
				// DataBaseAccess db = new DataBaseAccess(
				// getApplicationContext());
				// List<Song> l = db.getSongByPlaylist(selectedId);
				// if (l == null)
				// return;
				// db.savePlayingSong(l);
				// db.close();
				// sendBroadcast(new Intent(
				// PlayerService.INTENT_PLAYLIST_CHANGED));
				// }
				// }
				// // save data
				// updatePlaylistIndexById();
				// SharedPreferences sP = getSharedPreferences(
				// Common.SP_LIBRARY_NAME, Context.MODE_PRIVATE);
				// SharedPreferences.Editor ed = sP.edit();
				// ed.putInt(Common.SP_LIBRARY_PLAYING_TWO_LINE_INDEX,
				// mTwoLineListViewIndex);
				// ed.commit();
			}
		}
	}

	private void updatePlaylistIndex() {
		for (int i = 0; i < mListTwoLineItem.size(); i++) {
			if (mListTwoLineItem.get(i).name.equals(mNameOfSelectedPlaylist)) {
				mTwoLineListViewIndex = i;
				mTwoLineListViewIndexSaved = mTwoLineListViewIndex;
				break;
			}

		}
	}

	class InitTask extends AsyncTask<Integer, Void, Integer> {

		@Override
		protected Integer doInBackground(Integer... params) {
			int cmd = params[0];
			if (cmd == 1)// save
			{
				savePlayingSongData();
			} else if (cmd == 2)// apply
			{
				applyPlayingData();
			}
			return cmd;
		}

		@Override
		protected void onPostExecute(Integer result) {
			if (result == 1)// save
			{

			} else if (result == 2)// apply
			{
				mGridLibAdapter.setSelectedItem(mGridViewIndexSaved);
				fillData();
			}
		}

	}

	@Override
	public void onIndexChanged(int index) {
		switch (index) {
		case 0:// main lib
			mTsNumberRecored.setText("");
			break;
		case 1:// two line item
			mTsNumberRecored.setText(getString(R.string.lib_text_total_found)
					+ " " + mListTwoLineItem.size());
			break;
		case 2:// album item
			mTsNumberRecored.setText(getString(R.string.lib_text_total_found)
					+ " " + mListAlbum.size());
			if (!mAlbumLengthLoaded)
				new AlbumLengthUpdater().execute();
			break;
		case 3:// list item
			mTsNumberRecored.setText(getString(R.string.lib_text_total_found)
					+ " " + mListSong.size());
			break;
		}
	}

	private boolean mAlbumLengthLoaded;

	class AlbumLengthUpdater extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			List<Song> temp = new ArrayList<Song>();
			for (AlbumItem ai : mListAlbum) {
				temp.clear();
				if (mListMode == 0) // artist
				{
					temp.addAll(mDataBase.getSongsFromAlbum(ai.name, ai.artist));
				} else if (mListMode == 1)// genre
				{
					temp.addAll(mDataBase.getSongsFromAlbumAndGenre(ai.name,
							ai.artist, ai.genre));
				}
				ai.length = Utils.convertTimeToString(getAlbumLength(temp));
			}
			return null;
		}

		private int getAlbumLength(List<Song> l) {
			int length = 0;
			for (Song s : l) {
				length += s.getDuration();
			}
			return length;
		}

		@Override
		protected void onPostExecute(Void result) {
			mGridAlbumAdapter.notifyDataSetChanged();
			mAlbumLengthLoaded = true;
			new AlbumArtThumbUpdater().execute();
		}
	}

	class AlbumArtThumbUpdater extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			List<Song> temp = new ArrayList<Song>();
			for (AlbumItem ai : mListAlbum) {
				temp.clear();
				if (mListMode == 0) // artist
				{
					temp.addAll(mDataBase.getSongsFromAlbum(ai.name, ai.artist));
				} else if (mListMode == 1)// genre
				{
					temp.addAll(mDataBase.getSongsFromAlbumAndGenre(ai.name,
							ai.artist, ai.genre));
				}
				for (Song s : temp) {
					if (s.hasAlbumArt()) {
						ai.bitmapArt = s
								.extractAlbumArt(getApplicationContext());
						break;
					} else {
						String path = mDataBase.getAlbumArtPath(s.getId());
						if (path != null) {
							ai.albumArtPath = path;
							break;
						}
					}
				}

			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			mGridAlbumAdapter.notifyDataSetChanged();
		}
	}

}
